package io.renren.modules.generator.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import io.renren.common.exception.RRException;
import io.renren.common.utils.HttpUtils;
import io.renren.modules.generator.entity.WebPeople;
import io.renren.modules.generator.enums.PeopleAge;
import io.renren.modules.generator.enums.PeopleScode;
import io.renren.modules.generator.enums.WebPeopleScode;
import io.renren.modules.generator.vo.ageNumVo;
import org.apache.commons.lang.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;

import io.renren.modules.generator.dao.MissPeopleDao;
import io.renren.modules.generator.entity.MissPeopleEntity;
import io.renren.modules.generator.service.MissPeopleService;


@Service("missPeopleService")
public class MissPeopleServiceImpl extends ServiceImpl<MissPeopleDao, MissPeopleEntity> implements MissPeopleService {

    private final static Integer limit = 5;

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        QueryWrapper<MissPeopleEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("is_inner", 1);
        if (StringUtils.isNotBlank((String) params.get("missName"))) {
            wrapper.like("miss_name", params.get("missName"));
        }
        IPage<MissPeopleEntity> page = this.page(
                new Query<MissPeopleEntity>().getPage(params), wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public PageUtils queryPageByWeb(Map<String, Object> params) {
        QueryWrapper<MissPeopleEntity> wrapper = new QueryWrapper<>();
        wrapper.eq("is_inner", 0);
        if (StringUtils.isNotBlank((String) params.get("missName"))) {
            wrapper.like("miss_name", params.get("missName"));
        }
        IPage<MissPeopleEntity> page = this.page(
                new Query<MissPeopleEntity>().getPage(params), wrapper
        );

        return new PageUtils(page);
    }

    @Override
    public void saveMissPeople(String url) {
        saveWebMiss(url);

    }

    @Override
    public List<MissPeopleEntity> getSimilarPeople(Integer missId) {
        MissPeopleEntity missPeopleEntity = baseMapper.selectById(missId);
        return getMissPeople(missPeopleEntity);
    }

    @Override
    public void autoGetNewMissPeople() {
        try {
            String s = HttpUtils.sendGet(WebPeopleScode.URL.comment, null, null);
            List list = JSON.parseObject(s, List.class);

            List<Map> listMaps = JSONArray.parseArray(JSON.toJSONString(list), Map.class);

            String json = JSON.toJSONString(listMaps);
            List<WebPeople> webPeoples = JSON.parseArray(json, WebPeople.class);
            saveAllWebPeople(webPeoples);
        } catch (Exception e) {
            throw new RRException("连接超时请稍后再试");
        }


    }

    @Override
    public List<ageNumVo> missAgeNum() {
        List<String> birthday = baseMapper.getBirthday();
        List<ageNumVo> missAgeNums = new ArrayList<>();
        List<Integer> yearList = new ArrayList<>();
        //年龄处于0-6岁
        int six = 0;
        //年龄处于7-13岁
        int thirteen = 0;
        //年龄处于14-17岁
        int seventeen = 0;
        //年龄处于18-40岁
        int forty = 0;
        //年龄处于41-59岁
        int fiftyNine = 0;
        //年龄大于等于60岁
        int sixty = 0;
        //其他异常数据
        int other = 0;

        //获取丢失人口的丢失年龄
        for (String day : birthday) {
            try {
                String year = day.substring(0, 4);
                //出生年份
                int birthYear = Integer.parseInt(year);
                Calendar date = Calendar.getInstance();
                //当前年份
                int nowYear = date.get(Calendar.YEAR);
                int age = nowYear - birthYear;
                yearList.add(age);
            } catch (Exception e) {
                other++;
//                continue;
            }

        }
//        birthday.stream().map(day -> {
//            String year = day.substring(0, 4);
//            //出生年份
//            int birthYear = Integer.parseInt(year);
//            Calendar date = Calendar.getInstance();
//            //当前年份
//            int nowYear = date.get(Calendar.YEAR);
//            return nowYear - birthYear;
//        }).collect(Collectors.toList());

        //获取每个年龄段失踪人数数量
        for (Integer year : yearList) {
            if (year <= PeopleAge.SIX.scode) {
                six++;
            } else if (year <= PeopleAge.THIRTEEN.scode) {
                thirteen++;
            } else if (year <= PeopleAge.SEVENTEEN.scode) {
                seventeen++;
            } else if (year <= PeopleAge.FORTY.scode) {
                forty++;
            } else if (year <= PeopleAge.FIFTYNINE.scode) {
                fiftyNine++;
            } else {
                sixty++;
            }
        }
        missAgeNums.add(getAgeNumVo(six, PeopleAge.SIX.comment));
        missAgeNums.add(getAgeNumVo(thirteen, PeopleAge.THIRTEEN.comment));
        missAgeNums.add(getAgeNumVo(seventeen, PeopleAge.SEVENTEEN.comment));
        missAgeNums.add(getAgeNumVo(forty, PeopleAge.FORTY.comment));
        missAgeNums.add(getAgeNumVo(fiftyNine, PeopleAge.FIFTYNINE.comment));
        missAgeNums.add(getAgeNumVo(sixty, PeopleAge.SIXTY.comment));
        missAgeNums.add(getAgeNumVo(other, PeopleAge.OTHER.comment));
        return missAgeNums;
    }

    private ageNumVo getAgeNumVo(int num, String ageLevel){
        ageNumVo ageNumVo = new ageNumVo();
        ageNumVo.setAgeLevel(ageLevel);
        ageNumVo.setAgeNum(num);
        return ageNumVo;
    }

    private void saveAllWebPeople(List<WebPeople> webPeoples) {
        for (WebPeople webPeople : webPeoples) {
            try {
                MissPeopleEntity missPeopleEntity = new MissPeopleEntity();
                missPeopleEntity.setIsInner(WebPeopleScode.OUTER.value);
                if (WebPeopleScode.MAN.comment.equals(webPeople.getMissSex())) {
                    missPeopleEntity.setMissSex(WebPeopleScode.MAN.value);
                } else {
                    missPeopleEntity.setMissSex(WebPeopleScode.WOMAN.value);
                }
                //身高问题
                missPeopleEntity.setMissHeight(getMissPeopleHign(webPeople.getMissHigh()));
                missPeopleEntity.setMissName(webPeople.getMissName());
                missPeopleEntity.setMissPhoto(WebPeopleScode.PICPREFIX.comment + webPeople.getMissPic());
                missPeopleEntity.setContactsPhone(webPeople.getContactPhone());
                //未知-统一设为男性
                missPeopleEntity.setContactsSex(WebPeopleScode.MAN.value);
                missPeopleEntity.setContactsPeople(webPeople.getContactName());
                DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                missPeopleEntity.setCreateTime(df.format(LocalDateTime.now()));
                if (WebPeopleScode.YES.comment.equals(webPeople.getCallPol())) {
                    missPeopleEntity.setIsReport(WebPeopleScode.YES.value);
                } else {
                    missPeopleEntity.setIsReport(WebPeopleScode.NO.value);
                }
                if (WebPeopleScode.YES.comment.equals(webPeople.getBloodCollection())) {
                    missPeopleEntity.setIsBlood(WebPeopleScode.YES.value);
                } else {
                    missPeopleEntity.setIsBlood(WebPeopleScode.NO.value);
                }
                missPeopleEntity.setLostCourse(webPeople.getMissExperience());
                missPeopleEntity.setMissBirthday(webPeople.getMissBarth());
                missPeopleEntity.setMissDate(webPeople.getMissDate());
                missPeopleEntity.setMissFamily(webPeople.getOtherDesc());
                missPeopleEntity.setMissFeature(webPeople.getMissFaceText());
                String missAccess = webPeople.getMissAccess();
                //处理地域问题
                missAccess = dealArea(missAccess);
                missPeopleEntity.setMissLocate(missAccess);
                missPeopleEntity.setMissNativePlace(webPeople.getName());
                missPeopleEntity.setMissReward(webPeople.getMoney());
                baseMapper.insert(missPeopleEntity);
            } catch (Exception e) {
                continue;
            }
        }
    }

    private List<MissPeopleEntity> getMissPeople(MissPeopleEntity missPeopleEntity) {
        TreeMap<Integer, MissPeopleEntity> map = new TreeMap<>();
        Integer missHeight = missPeopleEntity.getMissHeight();
        Integer missSex = missPeopleEntity.getMissSex();
        Integer maxMissHeight = missHeight + limit;
        Integer miniMissHeight = missHeight - limit;
        String nativePlace = missPeopleEntity.getMissNativePlace();
        String missBirthday = missPeopleEntity.getMissBirthday();
        String missDate = missPeopleEntity.getMissDate();
        Integer isReport = missPeopleEntity.getIsReport();
        Integer isBlood = missPeopleEntity.getIsBlood();
        String locate = missPeopleEntity.getMissLocate();
        String provice = "";
        String city = "";
        String couny = "";
        //处理地域问题
        if (locate.length() > 6) {
            provice = locate.substring(0, 3);
            city = locate.substring(4, 7);
            couny = locate.substring(8);
        } else if (locate.length() > 3) {
            city = locate.substring(0, 3);
            couny = locate.substring(4, 7);
        } else {
            couny = locate;
        }
        String missDetailedAddress = missPeopleEntity.getMissDetailedAddress();
        String missReward = missPeopleEntity.getMissReward();
        List<MissPeopleEntity> list = baseMapper.selectList(new QueryWrapper<>());
        String finalCity = city;
        String finalProvice = provice;
        String finalCouny = couny;
        list.forEach(misspeople -> {
            Integer scode = 0;
            Integer height = misspeople.getMissHeight();
            //如果身高相似推荐分+10
            if (miniMissHeight <= height && height <= maxMissHeight) {
                scode += PeopleScode.HEIGHT.getScode();
            }
            //如果性别相同推荐分+15
            if (misspeople.getMissSex().equals(missSex)) {
                scode += PeopleScode.SEX.getScode();
            }
            //如果籍贯相同推荐分+60
            if (misspeople.getMissNativePlace().equals(nativePlace)) {
                scode += PeopleScode.NATIVE.getScode();
            }
            //如果生日相同推荐分+20
            if (misspeople.getMissBirthday().equals(missBirthday)) {
                scode += PeopleScode.BIRTHDAY.getScode();
            }
            //如果失踪日期相同推荐分+50
            if (misspeople.getMissDate().equals(missDate)) {
                scode += PeopleScode.MISSDATE.getScode();
            }
            //如果报案情况相同推荐分+5
            if (misspeople.getIsReport().equals(isReport)) {
                scode += PeopleScode.ISREPORT.getScode();
            }
            //如果采血情况相同推荐分+5
            if (misspeople.getIsBlood().equals(isBlood)) {
                scode += PeopleScode.ISBLOOD.getScode();
            }
            //如果丢失省相同推荐分+60
            if (misspeople.getMissLocate().substring(0, 3).equals(finalProvice)) {
                scode += PeopleScode.PROVICE.getScode();
            }
            //如果丢失市相同推荐分+70
            if (misspeople.getMissLocate().substring(4, 7).equals(finalCity)) {
                scode += PeopleScode.CITY.getScode();
            }
            //如果丢失县相同推荐分+80
            if (misspeople.getMissLocate().substring(8).equals(finalCouny)) {
                scode += PeopleScode.COUNY.getScode();
            }
            //如果丢失详细地址相同推荐分+100
            if (misspeople.getMissDetailedAddress().equals(missDetailedAddress)) {
                scode += PeopleScode.DETAIL.getScode();
            }
            //如果悬赏金相同推荐分+30
            if (misspeople.getMissReward().equals(missReward)) {
                scode += PeopleScode.REWARD.getScode();
            }

            map.put(scode, misspeople);

        });

        List<MissPeopleEntity> missPeoples = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            Map.Entry<Integer, MissPeopleEntity> lastEntry = map.pollLastEntry();
            if (i == 0) {
                continue;
            } else {
                missPeoples.add(lastEntry.getValue());
            }
        }

        return missPeoples;
    }

    private void saveWebMiss(String url) {
        MissPeopleEntity entity = new MissPeopleEntity();
        String missPhoto = null;
        String missName = null;
        Integer missHeight = null;
        Integer missSex = null;
        String missNativePlace = null;
        String missBirthday = null;
        String missDate = null;
        String missReward = null;
        Integer isReport = null;
        Integer isBlood = null;
        String missLocate = null;
        String missFamily = null;
        String lostCourse = null;
        String missFeature = null;

        try {
            Document doc = Jsoup.connect(url).get();
            Element img = doc.getElementById("img");
            missPhoto = img.attr("src");
            Elements infos = doc.getElementsByClass("infos");
            Element element = infos.get(0);
            //整体详情div集合
            Elements divs = element.getElementsByTag("div");
            //获取失踪人姓名
            Element nameDivs = divs.get(1);
            missName = nameDivs.text().split(" ")[0];
            //获取失踪人性别-身高
            Element highSex = divs.get(2);
            Elements highSexs = highSex.getElementsByTag("div");
            String sex = highSexs.get(1).getElementsByTag("span").get(0).text();
            if (sex.equals("男")) {
                missSex = 1;
            } else {
                missSex = 2;
            }
            String high = highSexs.get(2).getElementsByTag("span").get(0).text();
            missHeight = getMissPeopleHign(high);
            //获取失踪人籍贯-出生日期
            Element jiDate = divs.get(5);
            Elements jiDates = jiDate.getElementsByTag("div");
            missNativePlace = jiDates.get(1).getElementsByTag("span").get(0).text();
            missBirthday = jiDates.get(2).getElementsByTag("span").get(0).text();
            //获取失散日期-悬赏金额
            Element dateReward = divs.get(8);
            Elements dateRewards = dateReward.getElementsByTag("div");
            missDate = dateRewards.get(1).getElementsByTag("span").get(0).text();
            missReward = dateRewards.get(2).getElementsByTag("span").get(0).text();
            //获取报案-采血信息
            Element reportBlood = divs.get(11);
            Elements reportBloods = reportBlood.getElementsByTag("div");
            if ("否".equals(reportBloods.get(1).getElementsByTag("span").get(0).text())) {
                isReport = 2;
            } else {
                isReport = 1;
            }
            if ("否".equals(reportBloods.get(2).getElementsByTag("span").get(0).text())) {
                isBlood = 2;
            } else {
                isBlood = 1;
            }
            //获取失踪地点已-分割省市县
            Element location = divs.get(14);
            Elements locations = location.getElementsByTag("div");
            String gps = locations.get(1).getElementsByTag("span").get(0).text();
            missLocate = dealArea(gps);

            //获取特征描述-失散经过-家属附言
            Elements fl = doc.getElementsByClass("fl").get(6).getElementsByTag("div");
            Element element1 = fl.get(33);
            Elements ps = element1.getElementsByTag("p");
            //特征描述
            missFeature = ps.get(1).text();
            //失散经过
            lostCourse = ps.get(4).text();
            //家属附言
            missFamily = ps.get(7).text();

        } catch (Exception e) {
            log.error(e.getMessage());
            throw new RRException("失踪人口网站错误，无法连接-联系后台管理员修改网站url");
        }
        entity.setMissPhoto(missPhoto);
        entity.setMissName(missName);
        entity.setMissHeight(missHeight);
        entity.setMissSex(missSex);
        entity.setMissNativePlace(missNativePlace);
        entity.setMissBirthday(missBirthday);
        entity.setMissDate(missDate);
        entity.setMissReward(missReward);
        entity.setIsReport(isReport);
        entity.setIsBlood(isBlood);
        entity.setMissLocate(missLocate);
        entity.setMissFamily(missFamily);
        entity.setLostCourse(lostCourse);
        entity.setMissFeature(missFeature);
        entity.setIsInner(0);
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        entity.setCreateTime(df.format(LocalDateTime.now()));
        this.save(entity);
    }

    private String dealArea(String missLocate) {
        if (StringUtils.isNotBlank(missLocate)) {
            if (missLocate.length() > 6) {
                missLocate = missLocate.substring(0, 3) + "-" + missLocate.substring(3, 6) + "-" + missLocate.substring(6);
            } else if (missLocate.length() > 3) {
                missLocate = missLocate.substring(0, 3) + "-" + missLocate.substring(3);
            } else {
                return missLocate;
            }
        } else {
            missLocate = "";
        }
        return missLocate;
    }

    private int getMissPeopleHign(String high) {
        //去空格
        high = high.replaceAll(" ", "");

        Double aDouble = null;
        try {
            aDouble = Double.parseDouble(high);
        } catch (Exception e) {
            return 160;
        }
        if (aDouble < 2) {
            return (int) (aDouble * 100);
        } else {
            return Integer.valueOf(high);
        }
    }

}
